package kr.co.handysoft.smartPolice.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

import kr.co.handysoft.common.compress.Archiving;
import kr.co.handysoft.common.registry.SmartPoliceRegistry;
import kr.co.handysoft.smartPolice.vo.Constant;
import kr.co.handysoft.smartPolice.vo.FileProcessResult;
import kr.co.handysoft.smartPolice.vo.ProcessFile;
import net.sf.json.JSONObject;

public class FileInformationSenderHandler {

	private String success;
	private String fail;
	private String id;
	private String idKor;
	private Socket socket;
	private File tmpFile;
	private BufferedWriter out;

	public FileInformationSenderHandler(Socket socket) {
		this.socket = socket;
		try {
			this.tmpFile = File.createTempFile("~AIIT", ".tmp");
			out = new BufferedWriter(new FileWriter(this.tmpFile));
			System.out.println("tmpFile : " + this.tmpFile.getAbsolutePath());
		} catch (IOException e) {
			e.printStackTrace();
		}
	} 

	@SuppressWarnings("unchecked")
	public void invoke(File[] tgrFileArray, String successFolder, String failFolder) {
		success = successFolder;
		fail = failFolder;
		
		FileProcessResult result = new FileProcessResult(id, idKor);
		ArrayList<ProcessFile> fileCollection = (ArrayList<ProcessFile>)result.get(Constant.FILES);
		
		if (tgrFileArray != null){
			for (File tgrFile : tgrFileArray){
				processFile(tgrFile, fileCollection);
			}
			
			if (this.socket != null && this.socket.isConnected()){
				if (fileCollection.size() > 0){
					communicateServer(result, fileCollection.size());
				}
			}else{
				if (fileCollection.size() > 0){
					writeFile(result, fileCollection.size());
				}
			}
		}
	}


	private void processFile(File tgrFile, ArrayList<ProcessFile> result) {
		moveFile(tgrFile, success, result);
	}

	private boolean moveFile(File tgrFile, String movePath, ArrayList<ProcessFile> collection) {
		
		ProcessFile procFile = new ProcessFile(tgrFile, this.success);
		String fileName = procFile.getPathString() + "/" + tgrFile.getName() ;
		
		try {
			copyFile(tgrFile, new File(fileName));
			
			if (collection != null){
				collection.add(procFile);
			}
			
			tgrFile.delete();	
			
			return true;
		} catch (FileNotFoundException e) {
			return false;
		} catch (IOException e) {
			return false;
		}
	}

	private void writeFile(FileProcessResult result, int count) {
	
		String fileProcessResultString = Archiving.send(JSONObject.fromObject(result).toString()) + "\r\n";
		
		try {
			out.write(fileProcessResultString);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void communicateServer(FileProcessResult tgrFile, int count) {
		
		String fileProcessResultString = Archiving.send(JSONObject.fromObject(tgrFile).toString()) + "\r\n";
		
		OutputStream os_socket;
		
		try {
			
			os_socket = this.socket.getOutputStream();
			InputStream is_socket = this.socket.getInputStream();
			
			BufferedWriter bufferW = new BufferedWriter(new OutputStreamWriter(os_socket));
			BufferedReader bufferR = new BufferedReader(new InputStreamReader(is_socket));
			bufferW.write(fileProcessResultString);
			bufferW.flush(); 
			bufferR.readLine();
			
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	private void copyFile(File sourceFile, File destFile) throws IOException {
		 FileChannel source = null;
		 FileChannel destination = null;
		 
		 try {			 
			 source = new FileInputStream(sourceFile).getChannel();
			 destination = new FileOutputStream(destFile).getChannel();
			 destination.transferFrom(source, 0, source.size());
		 }finally {
			 if(source != null) source.close();
			 if(destination != null) destination.close();
		 }
	}

	public void setSystemId(String sId, String sIdKor) {
		id = sId;
		idKor = sIdKor;
	}

}
